require 'digest/sha1'
require 'paperclip'
class User < ActiveRecord::Base
  
  has_many :smessages,            #sent_messages
           :class_name => 'Message',
           :foreign_key => 'sender_id',
           :order => 'created_at DESC',
           :dependent => :destroy
  has_many :rmessages,            #received_messages
           :class_name => 'Message',
           :foreign_key => 'receiver_id',
           :order => 'created_at DESC',
           :dependent => :destroy         
  has_one :profile
  
  has_many :photos, :dependent => :destroy
  has_many :works, :dependent => :destroy           
  
  has_many :solved_requirements,
           :class_name => 'Requirement',
           :foreign_key => 'solver_id'

  has_many :requirements   
  has_many :comments
  has_many :favorite_requirements
  has_many :favorite_comments
  has_many :favorite_works
  has_many :fav_requirements,
           :through => :favorite_requirements,
           :source => :requirement,
           :order => "favorite_requirements.created_at"
  has_many :fav_comments,
           :through => :favorite_comments,
           :source => :comment,
           :order => "favorite_comments.created_at"
  has_many :fav_works,
           :through => :favorite_works,
           :source => :work,
           :order => "favorite_works.created_at"
           

  has_many :requirement_orders
  has_many :orders,
           :through => :requirement_orders,
           :source => :requirement
  
  has_many :friendships
  has_many :friends,
           :through => :friendships,
           :conditions => "status = 'accepted'",
           :order => :username
  has_many :requested_friends,              #别人向自己申请朋友
           :through => :friendships,
           :source  => :friend,
           :conditions => "status = 'requested'",
           :order => "friendships.created_at"
  has_many :pending_friends,                #自己向别人申请朋友
           :through => :friendships,
           :source  => :friend,
           :conditions => "status = 'pending'",
           :order => "friendships.created_at"

  has_many :visitors,
           :class_name => "Visitor",
           :foreign_key => :visited_id,
           :order => 'updated_at DESC',
           :dependent => :destroy
           
  has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" },
                             :default_url => "/images/heads/#{1+rand(4)}.jpg"
  attr_protected :avatar_file_size, :avatar_content_type
  validates_attachment_size :avatar, :less_than => 5.megabytes, :message => "图片不超过5m"
  validates_attachment_content_type :avatar, :content_type => ['image/jpeg', 'image/pjpeg', 'image/jpg'  ,'image/png','image/bmp','image/gif'], :message => "请上传图像文件"
  
  
  apply_simple_captcha :message => "不正确", :add_to_base => false                
  attr_accessor :current_passwd
  attr_accessor :remember_me
  attr_accessor :passwd_confirmation
  USERNAME_MIN_LENGTH = 6
  USERNAME_MAX_LENGTH = 20
  PASSWORD_MIN_LENGTH = 6
  PASSWORD_MAX_LENGTH = 20
  EMAIL_MAX_LENGTH = 50
  USERNAME_RANGE = USERNAME_MIN_LENGTH..USERNAME_MAX_LENGTH
  PASSWORD_RANGE = PASSWORD_MIN_LENGTH..PASSWORD_MAX_LENGTH
  
  EMAIL_SIZE = 30
  USERNAME_SIZE = 20
  PASSWORD_SIZE = 10
  
  validates_uniqueness_of :username,:email, :message => "已注册"
  validates_presence_of :passwd, :on => :create, :message => "不能为空"
  validates_confirmation_of :passwd, :on => :create, :message => "不一致"
  validates_presence_of :username, :email, 
                        :message => "不能为空"
  
  validates_length_of :username, :within => USERNAME_RANGE, :message => "长度6-20位"
  validates_length_of :passwd, :within => PASSWORD_RANGE, :message => "长度6-20位", :on => :create
  validates_length_of :email, :maximum => EMAIL_MAX_LENGTH, :message => "不超过50位"
  
  
  
  validates_format_of :username,
                      :with => /^[a-z0-9_]*$/i,
                      :message => "只能包含字母数字和下划线"
  validates_format_of :email,
                      :with => /^[a-z0-9._%-]+@([a-z0-9-]+\.)+[a-z]{2,4}$/i,
                      :message => "不正确"
  validate :validate_name_and_company                   
  before_create :make_activation_code 
  before_save :change_activation_code
#  define_index do
#      indexes username
#      indexes email
#      set_property :delta => true #这个是实时索引,注意,你的model表中得有delta这个字段,类型是boolean
#  end
  def validate_name_and_company
    if self.role == DEMANDER
     errors.add(:name,"不空") if self.name.blank?  
     errors.add(:company,"不空") if self.company.blank? 
     errors.add(:tel,"不正确") if (self.tel=~/^\d{3,4}[-]\d{7,8}$/)==nil  
    end
  end

 # Activates the user in the database.
  def activate!
    self.activated_at = Time.now
    self.activation_code = nil
    save(false)
  end

  def active?
    # the existence of an activation code means they have not activated yet
    activation_code.nil?
  end
  
  def check!
    self.pwd_check_code = nil
    save(false)
  end
  
  def checked?
    pwd_check_code.nil?
  end
  
  def self.exist?(params)
    find_by_username_and_email(params[:user][:username],params[:user][:email])
  end

  def login!(session)
    session[:user_id] = id#self.id
  end
  
  def self.logout!(session,cookies)
    session[:user_id] = nil
    cookies.delete(:authorization_token)
  end
  
  def clear_password!
    self.passwd = nil #若用password=nil 将产生一个值为nil的局部变量，覆盖类属性
    self.passwd_confirmation = nil
    self.current_passwd = nil
  end
  
  def correct_password?(params)
    expected_password = User.encrypted_password(params[:user][:current_passwd],self.salt)
    success1 = self.password == expected_password
    success2 = params[:user][:passwd].length >= 6
    success3 = params[:user][:passwd] == params[:user][:passwd_confirmation]
    errors.add(:current_passwd,"不正确") unless success1
    errors.add(:passwd,"长度为6-20") unless success2
    errors.add(:passwd_confirmation,"不一致") unless success3
    success1 && success2 && success3
  end
  
  def right_password?(params)
    success1 = params[:user][:passwd].length >= 6
    success2 = params[:user][:passwd] == params[:user][:passwd_confirmation]
    errors.add(:passwd,"长度为6-20") unless success1
    errors.add(:passwd_confirmation,"不一致") unless success2
    success1 && success2
  end
  
  def update_password(params)
    self.passwd = params[:user][:passwd]
    self.save(false)
  end

  def remember!(cookies)
    cookie_expiration = 10.years.from_now
    cookies[:remember_me] = { :value => "1", :expires => cookie_expiration }
    self.authorization_token = unique_identifier
    self.update_attribute(:authorization_token,self.authorization_token)
    cookies[:authorization_token] = { :value => authorization_token, :expires => cookie_expiration }
  end

  def forget!(cookies)
    cookies.delete(:remember_me)
    cookies.delete(:authorization_token)
  end

  def remember_me?
    remember_me =="1"
  end

  
  def self.authenticate(username,passwd)
        user = User.find_by_username(username)
        if user
            expected_password = encrypted_password(passwd,user.salt)
            if expected_password != user.password
                user = nil
            end
        end
        user
  end
  
  def save_pwd_checkcode
    make_pwd_check_code
  end
  
  def passwd
    @passwd
  end

  def passwd=(pwd)
    @passwd = pwd
    return if pwd.blank?
    create_salt
    self.password = User.encrypted_password(self.passwd,self.salt)
  end
  
  
  private
  def unique_identifier
    Digest::SHA1.hexdigest("#{username}:#{password}")
  end
  
  def create_salt
    self.salt = self.object_id.to_s
  end

  def self.encrypted_password(pwd,salt)#对密码进行加密
     string_to_hash = pwd + "zly" + salt
     Digest::SHA1.hexdigest(string_to_hash)
  end
  
  def make_activation_code
    self.activation_code = Digest::SHA1.hexdigest(string_for_hash(create_salt))
  end
  
  def change_activation_code
    if self.email_changed? && !active?
      make_activation_code
    end
  end
 
  def make_pwd_check_code
    self.pwd_check_code = Digest::SHA1.hexdigest(string_for_hash(self.password))
    self.save(false)
  end
 
  def string_for_hash(salt)
    salt + Time.now.to_s
  end
end
